#!/usr/bin/python -B

from string import Template, upper, replace

from ApiUtil import outputCode
from ApiUtil import typeIsVoid

from ApiCodeGen import *

from RegalContextInfo import cond

from RegalDispatchShared import dispatchSourceTemplate, apiDispatchFuncInitCode

##############################################################################################

# CodeGen for PPAPI dispatch functions

def apiPpapiFuncDefineCode(apis, args):

  code = ''

  for api in apis:

    if api.name=='gl':

      for function in api.functions:
        if not function.needsContext:
          continue
        if getattr(function,'esVersions',None)==None or 2.0 not in function.esVersions:
          continue
        if getattr(function,'regalOnly',False)==True:
          continue

        name   = function.name
        params = paramsDefaultCode(function.parameters, True)
        callParams = paramsNameCode(function.parameters)

        # Workaround for const difference between Regal.h and Pepper API

        if function.name=='glShaderSource':
          callParams = callParams.replace(', string,',',const_cast<const GLchar **>(string),')

        rType  = typeCode(function.ret.type)
        ppapiName = name
        if ppapiName.startswith('gl'):
          ppapiName = ppapiName[2:]

        code += 'static %sREGAL_CALL %s%s(%s) \n{\n' % (rType, 'ppapi_', name, params)
        code += '  Internal("ppapi_%s","()");\n' % name
        code += '  RegalContext * rCtx = REGAL_GET_CONTEXT();\n'
        code += '  RegalAssert(rCtx)\n'
        code += '  RegalAssert(rCtx->ppapiES2)\n'
        code += '  RegalAssert(rCtx->ppapiES2->%s)\n'%(ppapiName)
        code += '  RegalAssert(rCtx->ppapiResource)\n'
        if not typeIsVoid(rType):
          code += '  %s ret = ' % rType
        else:
          code += '  '
        if len(callParams):
          callParams = 'rCtx->ppapiResource, %s'%callParams
        else:
          callParams = 'rCtx->ppapiResource'
        code += 'rCtx->ppapiES2->%s(%s);\n' % ( ppapiName, callParams )
        if not typeIsVoid(rType):
          code += '  return ret;\n'
        code += '}\n\n'

  return code

def apiPpapiFuncInitCode(apis, args):

  code = '// OpenGL ES 2.0 only\n'

  for api in apis:

    if api.name=='gl':

      for function in api.functions:
        if not function.needsContext:
          continue
        if getattr(function,'esVersions',None)==None or 2.0 not in function.esVersions:
          continue

        name   = function.name
        params = paramsDefaultCode(function.parameters, True)
        callParams = paramsNameCode(function.parameters)
        rType  = typeCode(function.ret.type)

        code += '  tbl.%s = %s_%s;\n' % ( name, 'ppapi', name )

  return code

def generatePpapiSource(apis, args):

  funcDefine = apiPpapiFuncDefineCode( apis, args )
  funcInit   = apiPpapiFuncInitCode  ( apis, args )

  # Output

  substitute = {}

  substitute['LICENSE']         = args.license
  substitute['AUTOGENERATED']   = args.generated
  substitute['COPYRIGHT']       = args.copyright
  substitute['DISPATCH_NAME'] = 'Ppapi'
  substitute['LOCAL_INCLUDE'] = '#include <ppapi/c/ppb_opengles2.h>'
  substitute['LOCAL_CODE']    = ''
  substitute['API_DISPATCH_FUNC_DEFINE'] = funcDefine
  substitute['API_DISPATCH_FUNC_INIT'] = funcInit
  substitute['API_DISPATCH_GLOBAL_FUNC_INIT'] = ''
  substitute['IFDEF'] = '#if REGAL_DRIVER && REGAL_SYS_PPAPI\n'
  substitute['ENDIF'] = '#endif\n'

  outputCode( '%s/RegalDispatchPpapi.cpp' % args.srcdir, dispatchSourceTemplate.substitute(substitute))

